/*
 * Copyright (C) 2025 ameise <ameise.wang@gmail.com> - All Rights Reserved
 *
 * This file is part of e3time.
 *
 * e3time is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * e3time is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with e3time. If not, see <https://www.gnu.org/licenses/>.
 */

package main

import (
	"fmt"
	time "gitee.com/ameise84/e3time"
	"log"
	"sync"
	"sync/atomic"
)

type handler struct {
}

func (ts *handler) OnTimer(tr time.Timer, fireAt time.Time) {
	log.Printf(" %v triggger by handler[%s]\n", tr.Context(), fireAt.Format(time.LayoutMs))
}

type event struct {
	id uint64
}

func (ts *event) UniqueID() uint64 {
	return ts.id
}

func main() {
	fmt.Println("---TestTimer---")
	var a int64
	atomic.AddInt64(&a, 1)
	atomic.AddInt64(&a, 1)
	wrap := time.WrapTimerHandler(2)
	group := time.NewTimerHolder(nil)

	e1 := event{id: 1}
	_ = group.NewTick(wrap, &e1, 10*time.Second, time.InfiniteTimes)
	log.Printf("set 10sec tick at:%s", time.Now().String())
	e2 := event{id: 2}
	_ = group.NewTimer(wrap, &e2, 2*time.Second)
	log.Printf("set 2sec timer at:%s", time.Now().String())
	h := &handler{}
	e3 := event{id: 3}
	_ = group.NewTick(h, &e3, 1*time.Second, time.InfiniteTimes)
	log.Printf("set 1sec tick at:%s", time.Now().String())

	wg := sync.WaitGroup{}
	maxC := 100
	v := 0
	wg.Add(maxC)
	t2x := 0
	go func() {
		log.Println("start")
	loop:
		for {
			select {
			case trigger := <-wrap.C():
				if trigger.Timer().Context().(*event).id == 1 {
					log.Printf("t1[%v] triggger on time[%s]\n", trigger.Timer().Context(), trigger.Format(time.LayoutSec))
				} else {
					log.Printf("t2[%v] triggger on time[%s]->n[%d]\n", trigger.Timer().Context(), trigger.Format(time.LayoutSec), 1)
					time.Sleep(20 * time.Second)
					if t2x == 0 {
						trigger.Timer().Reset(2 * time.Second)
						t2x = 1
					} else if t2x == 1 {
						log.Printf("fast\n")
						trigger.Timer().Reset(4 * time.Second)
						_ = time.FastForward(3 * time.Second)
						t2x = 2
					}
				}
				wg.Done()
				v += 1
				if v >= maxC {
					break loop
				}
			}
		}
	}()
	wg.Wait()
}
